package com.gary.aspect;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.gary.annotations.CheckDataPermission;
import com.gary.bean.DataPermissionEntity;
import com.gary.page.Page;
import com.gary.util.DataPermissionUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.sql.Struct;
import java.util.HashMap;
import java.util.Map;

/**
 * 检查数据权限
 *
 * @author Homan Liang
 * @date 2019/10/28
 */
@Order(2)
@Aspect
@Component
public class CheckDataPermissionAspect {
    /**
     * 日志
     */
    private static final Logger logger = LoggerFactory.getLogger(CheckDataPermissionAspect.class);

//    @Resource
//    private IDataPermissionService dataPermissionService;

    /**
     * 切入点为 checkDataPermission 的方法
     *
     * @param checkDataPermission 检查数据权限注解
     */
    @Pointcut("@annotation(checkDataPermission)")
    public void joinPointExpression(CheckDataPermission checkDataPermission) {
    }

    /**
     * 在方法执行之前进行数据权限检查
     *
     * @param joinPoint           切入点
     * @param checkDataPermission 数据权限注解
     * @throws Exception 异常
     */
    @Around("joinPointExpression(checkDataPermission)")
    public Object beforeMethod(ProceedingJoinPoint joinPoint, CheckDataPermission checkDataPermission) throws Throwable {
        logger.info("检查数据权限==CheckDataPermissionAspect==beforeMethod==开始");

        Object[] argObjs = joinPoint.getArgs();
        try {
            String sessionId = "";
            HttpServletRequest request = null;
            Page page = null;
            DataPermissionEntity dataPermissionEntity = null;
            // 循环获取参数
            if (!ObjectUtil.isNull(argObjs) && argObjs.length > 0) {
                for (Object argObj : argObjs) {
                    if (argObj instanceof HttpServletRequest) {
                        // 请求信息
                        request = (HttpServletRequest) argObj;
                        // session id
                        sessionId = "";
//                        sessionId = Cookies.get(request, BackendConstant.SESSION_ID);
                    }
                    if (argObj instanceof Page) {
                        page = (Page) argObj;
                    }
                    if (argObj instanceof DataPermissionEntity) {
                        dataPermissionEntity = (DataPermissionEntity) argObj;
                    }
                }
            }
            if (ObjectUtil.isNull(request)) {
//                throw new BackendException("数据权限检查方法 HttpServletRequest 参数没有传入");
            }
            if (StrUtil.isEmpty(sessionId)) {
//                throw new BackendException(BaseResponse.NOLOGIN_RESULT.getResponseMsgCn(), BaseResponse.NOLOGIN_RESULT.getResponseCode());
            }
            // 是否需要设置数据权限
            boolean isNeedToSetDataPermission = DataPermissionUtils.isNeedToSetDataPermission(page, dataPermissionEntity);
            if (isNeedToSetDataPermission) {
                logger.info("检查数据权限==CheckDataPermissionAspect==beforeMethod==需要设置数据权限");
                String reqUri = request.getRequestURI();
                logger.info("检查数据权限==CheckDataPermissionAspect==beforeMethod==当前接口URI：{}", reqUri);
                // 获取数据权限拼凑 SQL 参数
                Map<String, Object> mapDataPermissionParam = new HashMap<>();
//                Map<String, Object> mapDataPermissionParam = dataPermissionService.getDataPermissionParam(sessionId, reqUri);
//                logger.info("检查数据权限==CheckDataPermissionAspect==beforeMethod==设置前，数据权限参数：{}", JsonUtil.toJson(mapDataPermissionParam));
                // 设置数据权限
                DataPermissionUtils.setDataPermissionExtraParam(page, dataPermissionEntity, mapDataPermissionParam
                        , checkDataPermission.defaultQueryAll());
//                logger.info("检查数据权限==CheckDataPermissionAspect==beforeMethod==设置后，数据权限参数：{}", JsonUtil.toJson(mapDataPermissionParam));
            }
        } catch (Exception e) {

        }
//        } catch (BackendException be) {
//            logger.error("检查数据权限==CheckDataPermissionAspect==beforeMethod==异常：", be);
//            throw be;
//        } catch (Exception e) {
//            logger.error("检查数据权限==CheckDataPermissionAspect==beforeMethod==异常：", e);
//            throw new BackendException("接口数据权限检查异常", BaseResponse.EXCEPTION_RESULT.getResponseCode());
//        }
        return joinPoint.proceed(argObjs);
    }
}
